package com.example.func.annotation;

import com.example.func.enums.OpType;
import com.example.func.enums.Scenario;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 审计日志记录注解
 * 用于标记需要记录审计信息的方法，支持动态获取实体信息
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuditLog {
    
    /**
     * 模块名称
     * @return 模块名称
     */
    String module() default "";

    /**
     * 业务场景（包含模块与可选的 serviceName）
     * 若不为 NONE，切面将优先使用此值
     */
    Scenario scenario() default Scenario.NONE;

    /**
     * 业务 Bean 名称
     * 用于在切面中通过 ApplicationContext 动态获取对应的 Bean
     * 该 Bean 应该包含根据 ID 获取实体的方法
     * @return Spring 容器中的 Bean 名称
     */
    String serviceName() default "";

    /**
     * 操作类型
     * 用于区分当前操作是新增、修改还是删除
     * @return 操作类型枚举
     */
    OpType opType() default OpType.CREATE;

    /**
     * 根据ID获取实体的方法名
     * 该方法应该在 serviceName 指定的 Bean 中存在
     * 方法签名应该为：EntityType getById(Long id) 或类似形式
     * @return 方法名称
     */
    String getEntityMethod() default "getById";

    /**
     * 实体ID参数名
     * 用于从方法参数中提取实体ID
     * 支持 SpEL 表达式，如 "#id" 或 "#user.id"
     * @return 参数名或SpEL表达式
     */
    String entityIdParam() default "id";

    /**
     * 操作描述
     * 用于记录具体的操作内容
     * @return 操作描述
     */
    String description() default "";

    /**
     * 是否记录请求参数
     * @return 是否记录请求参数
     */
    boolean logRequest() default true;

    /**
     * 是否记录响应结果
     * @return 是否记录响应结果
     */
    boolean logResponse() default true;

    /**
     * 是否记录实体变更前后的状态
     * @return 是否记录实体状态
     */
    boolean logEntityState() default true;

    /**
     * 审计级别
     * @return 审计级别
     */
    AuditLevel level() default AuditLevel.INFO;

    /**
     * 审计级别枚举
     */
    enum AuditLevel {
        /**
         * 信息级别
         */
        INFO,
        /**
         * 警告级别
         */
        WARN,
        /**
         * 错误级别
         */
        ERROR,
        /**
         * 关键操作级别
         */
        CRITICAL
    }
}
